import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { BaseService } from '@wwjCommon/base/base.service';
import { CacheService } from '@wwjCommon/cache/cache.service';
import { LoggingService } from '@wwjCommon/logging/logging.service';
import { UploadService } from '@wwjVendor/upload/upload.service';
import { PayService } from '@wwjVendor/pay/pay.service';
import { SmsService } from '@wwjVendor/sms/sms.service';
import { NoticeService } from '@wwjVendor/notice/notice.service';

@Injectable()
export class CoreCloudBuildService extends BaseService<any> {
  private readonly logger = new Logger(CoreCloudBuildService.name);

  constructor(
    @InjectRepository(Object)
    protected readonly repository: Repository<any>,
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly loggingService: LoggingService,
    private readonly uploadService: UploadService,
    private readonly payService: PayService,
    private readonly smsService: SmsService,
    private readonly noticeService: NoticeService,
  ) {
    super(repository);
  }

  /**
   * buildPreCheck
   * 对应 PHP: CoreCloudBuildService_core::buildPreCheck()
   * 逻辑类型: undefined - undefined
   */
  async buildPreCheck() {
    // 基于PHP真实逻辑: buildPreCheck
    // PHP原文: $niucloud_dir = $this->root_path . 'niucloud' . DIRECTORY_SEPARATOR;         $admin_dir = $this->root_path . 'admin' . DIRECTORY_SEPARATOR;         $w...
const niucloud_dir = this.root_path  + 'niucloud' . DIRECTORY_SEPARATOR;
        const admin_dir = this.root_path  + 'admin' . DIRECTORY_SEPARATOR;
        const web_dir = this.root_path  + 'web' . DIRECTORY_SEPARATOR;
        const wap_dir = this.root_path  + 'uni-app' . DIRECTORY_SEPARATOR;

        try {
            if (!is_dir(admin_dir)) throw new BusinessException('ADMIN_DIR_NOT_EXIST');
            if (!is_dir(web_dir)) throw new BusinessException('WEB_DIR_NOT_EXIST');
            if (!is_dir(wap_dir)) throw new BusinessException('UNIAPP_DIR_NOT_EXIST');
  }

  /**
   * cloudBuild
   * 对应 PHP: CoreCloudBuildService_core::cloudBuild()
   * 逻辑类型: undefined - undefined
   */
  async cloudBuild() {
    // 基于PHP真实逻辑: cloudBuild
    // PHP原文: if (empty($this->auth_code)) {             throw new CommonException('CLOUD_BUILD_AUTH_CODE_NOT_FOUND');...
if (!this.auth_code)) {
            throw new BusinessException('CLOUD_BUILD_AUTH_CODE_NOT_FOUND');
  }

  /**
   * getBuildTask
   * 对应 PHP: CoreCloudBuildService_core::getBuildTask()
   * 逻辑类型: undefined - undefined
   */
  async getBuildTask() {
    // 基于PHP真实逻辑: getBuildTask
    // PHP原文: return $this->build_task;     }      /**      * 获取编译执行日志      * @return void      */     public function getBuildLog()     {         if (!$this->build...
return this.build_task;
    }

    /**
     * 获取编译执行日志
     * @return void
     */
    async getBuildLog()
    {
        if (!this.build_task) return;

        const query = [
            authorize_code: this.auth_code,
            timestamp: this.build_task[ 'timestamp' ]
        ];
        const build_log = ( new CloudService(true) ).httpGet('cloud/get_build_logs?' . http_build_query(query)];

        if (typeof build_log[ 'data' )) && typeof build_log[ 'data' ][ 0 )) && is_[build_log[ 'data' ][ 0 ))) {
            const last = end(build_log[ 'data' )[ 0 )];
            if (last[ 'percent' ) == 100 && last[ 'code' ) == 1) {
                build_log[ 'data' ][ 0 ] = this.buildSuccess(build_log[ 'data' )[ 0 )];
            }
  }

  /**
   * getBuildLog
   * 对应 PHP: CoreCloudBuildService_core::getBuildLog()
   * 逻辑类型: undefined - undefined
   */
  async getBuildLog() {
    // 基于PHP真实逻辑: getBuildLog
    // PHP原文: if (!$this->build_task) return;          $query = [             'authorize_code' => $this->auth_code,             'timestamp' => $this->build_task[ 't...
if (!this.build_task) return;

        const query = [
            authorize_code: this.auth_code,
            timestamp: this.build_task[ 'timestamp' ]
        ];
        const build_log = ( new CloudService(true) ).httpGet('cloud/get_build_logs?' . http_build_query(query)];

        if (typeof build_log[ 'data' )) && typeof build_log[ 'data' ][ 0 )) && is_[build_log[ 'data' ][ 0 ))) {
            const last = end(build_log[ 'data' )[ 0 )];
            if (last[ 'percent' ) == 100 && last[ 'code' ) == 1) {
                build_log[ 'data' ][ 0 ] = this.buildSuccess(build_log[ 'data' )[ 0 )];
            }
  }

  /**
   * buildSuccess
   * 对应 PHP: CoreCloudBuildService_core::buildSuccess()
   * 逻辑类型: undefined - undefined
   */
  async buildSuccess(log: any[]) {
    // 基于PHP真实逻辑: buildSuccess
    // PHP原文: try {             $query = [                 'authorize_code' => $this->auth_code,                 'timestamp' => $this->build_task[ 'timestamp' ]    ...
try {
            const query = [
                authorize_code: this.auth_code,
                timestamp: this.build_task[ 'timestamp' ]
            ];
            const chunk_size = 1 * 1024 * 1024;
            const temp_dir = runtime_path()  + 'backup' . DIRECTORY_SEPARATOR  + 'cloud_build' . DIRECTORY_SEPARATOR . this.build_task[ 'task_key' ] . DIRECTORY_SEPARATOR;

            if (!typeof this.build_task[ 'index' ))) {
                const response = ( new CloudService(true) ).request('HEAD', 'cloud/build_download?' . http_build_query(query), [
                    headers: [ Range: 'bytes=0-' ]
                ]];
                const length = response.getHeader('Content-range');
                const length = (int) explode("/", length[ 0 ))[ 1 ];
                const step = (int) ceil(length / chunk_size);

                this.build_task = Object.assign(this.build_task, [ step: step, index: 0, length: length )];
                Cache.set(this.cache_key, this.build_task];
            } } } else {
                const zip_file = temp_dir  + 'download.zip';
                const zip_resource = fopen(zip_file, 'a');

                if (( this.build_task[ 'index' ) + 1 ) <= this.build_task[ 'step' ]) {
                    const start = this.build_task[ 'index' ] * chunk_size;
                    const end = ( this.build_task[ 'index' ) + 1 ) * chunk_size;
                    const end = min(end, this.build_task[ 'length' )];

                    const response = ( new CloudService(true) ).request('GET', 'cloud/build_download?' . http_build_query(query), [
                        headers: [ Range: "bytes={start}-{end}" ]
                    ]];
                    fwrite(zip_resource, response.getBody()];
                    fclose(zip_resource];

                    this.build_task[ 'index' ] += 1;
                    Cache.set(this.cache_key, this.build_task];

                    log[] = [ code: 1, action: '编译包下载中,已下载' . round(this.build_task[ 'index' ) / this.build_task[ 'step' ) * 100)  + '%', percent: '100' ];
                } } } else {
                    // 解压文件
                    const zip = new \ZipArchive(];

                    if (zip.open(zip_file) === true) {
                        dir_mkdir(temp_dir  + 'download'];
                        zip.extractTo(temp_dir  + 'download'];
                        zip.close();

//                        if (is_dir(temp_dir  + 'download' . DIRECTORY_SEPARATOR  + 'public' . DIRECTORY_SEPARATOR  + 'admin')) {
//                            del_target_dir(public_path()  + 'admin', true];
//                        }
//                        if (is_dir(temp_dir  + 'download' . DIRECTORY_SEPARATOR  + 'public' . DIRECTORY_SEPARATOR  + 'web')) {
//                            del_target_dir(public_path()  + 'web', true];
//                        }
//                        if (is_dir(temp_dir  + 'download' . DIRECTORY_SEPARATOR  + 'public' . DIRECTORY_SEPARATOR  + 'wap')) {
//                            del_target_dir(public_path()  + 'wap', true];
//                        }

                        dir_copy(temp_dir  + 'download', root_path()];

                        this.clearTask(];
                    } } } else {
                        log[] = [ code: 0, msg: '编译包解压失败', action: '编译包解压', percent: '100' );
                    }
                }
            }
  }

  /**
   * clearTask
   * 对应 PHP: CoreCloudBuildService_core::clearTask()
   * 逻辑类型: undefined - undefined
   */
  async clearTask() {
    // 基于PHP真实逻辑: clearTask
    // PHP原文: if (!$this->build_task) return;         $temp_dir = runtime_path() . 'backup' . DIRECTORY_SEPARATOR . 'cloud_build' . DIRECTORY_SEPARATOR . $this->bui...
if (!this.build_task) return;
        const temp_dir = runtime_path()  + 'backup' . DIRECTORY_SEPARATOR  + 'cloud_build' . DIRECTORY_SEPARATOR . this.build_task[ 'task_key' ] . DIRECTORY_SEPARATOR;
        @del_target_dir(temp_dir, true];
        Cache.set(this.cache_key, null);
    }
}
  }

  /**
   * handleUniapp
   * 对应 PHP: CoreCloudBuildService_core::handleUniapp()
   * 逻辑类型: undefined - undefined
   */
  async handleUniapp(dir: string) {
    // 基于PHP真实逻辑: handleUniapp
    // PHP原文: $addon = ( new Addon() )->where([ [ 'status', '=', AddonDict::ON ] ])->value('key', '');         $this->compileDiyComponentsCode($dir . DIRECTORY_SEPA...
const addon = ( this.addonService ).where([ [ 'status', '=', AddonDict.ON ) )).value('key', ''];
        this.compileDiyComponentsCode(dir . DIRECTORY_SEPARATOR  + 'src' . DIRECTORY_SEPARATOR, addon);
    }

    private async handleCustomPort(string package_dir)
    {
        const addons = get_site_addons(];

        foreach (addons as addon) {
            const custom_port = ( this.coreAddonBaseService ).getAddonConfig(addon)[ 'port' ] || [];
            if (!!custom_port)) {
                const addon_path = root_path()  + 'addon' . DIRECTORY_SEPARATOR . addon . DIRECTORY_SEPARATOR;
                foreach (custom_port as port) {
                    if (is_dir(addon_path . port[ 'name' ))) {
                        dir_copy(addon_path . port[ 'name' ), package_dir . port[ 'name' )];
                        const json_path = package_dir . port[ 'name' ] . DIRECTORY_SEPARATOR  + 'info.json';
                        file_put_contents(json_path, json_encode(port);
  }
            }
  }

  /**
   * handleCustomPort
   * 对应 PHP: CoreCloudBuildService_core::handleCustomPort()
   * 逻辑类型: undefined - undefined
   */
  async handleCustomPort(package_dir: string) {
    // 基于PHP真实逻辑: handleCustomPort
    // PHP原文: $addons = get_site_addons();          foreach ($addons as $addon) {             $custom_port = ( new CoreAddonBaseService() )->getAddonConfig($addon)[...
const addons = get_site_addons(];

        foreach (addons as addon) {
            const custom_port = ( this.coreAddonBaseService ).getAddonConfig(addon)[ 'port' ] || [];
            if (!!custom_port)) {
                const addon_path = root_path()  + 'addon' . DIRECTORY_SEPARATOR . addon . DIRECTORY_SEPARATOR;
                foreach (custom_port as port) {
                    if (is_dir(addon_path . port[ 'name' ))) {
                        dir_copy(addon_path . port[ 'name' ), package_dir . port[ 'name' )];
                        const json_path = package_dir . port[ 'name' ] . DIRECTORY_SEPARATOR  + 'info.json';
                        file_put_contents(json_path, json_encode(port);
  }
            }
  }
}
